package com.dexgdx.game;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.graphics.g2d.ParticleEffectPool;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.dexgdx.game.action.SteadyAction;
import com.dexgdx.game.action.attack.DexTrailAttackAction;
import com.dexgdx.game.action.movement.MovementAction;
import com.dexgdx.game.action.pack.ActionPack;
import com.dexgdx.game.action.pack.DexMissileAttackActionPack;
import com.dexgdx.game.action.pack.DexTrailAttackActionPack;
import com.dexgdx.game.constants.EMoveDirection;
import com.dexgdx.game.initializer.DefaultConstants;
import com.dexgdx.game.manager.ActionData;
import com.dexgdx.game.manager.ActionManager;
import com.dexgdx.game.manager.GameData;
import com.dexgdx.game.manager.ActorManager;
import com.dexgdx.game.manager.AnimationData;
import com.dexgdx.game.manager.AnimationManager;
import com.dexgdx.game.manager.ParticleData;
import com.dexgdx.game.manager.ParticleManager;
import com.dexgdx.game.structure.actor.AbstractActor;
import com.dexgdx.game.structure.actor.EnemyActor;
import com.dexgdx.game.structure.actor.PlayerActor;
import com.dexgdx.game.structure.base.BaseObject;
import com.dexgdx.game.structure.base.BasePoint;
import com.dexgdx.game.structure.base.BaseRegion;
import com.dexgdx.game.structure.component.SelectionRectangle;
import com.dexgdx.game.util.pathcalc.DirectPathCalcSession;
import com.dexgdx.game.util.pathcalc.WallHugDirectPathCalcSession;
import com.dexgdx.game.util.trajectory.node.TrajectoryNode;

public class Game {
	
	private static boolean isInitialized;
	
	public static DefaultConstants defaultConstants;
	
	public static GameData gameData;
	public static ActionData actionData;
	public static ParticleData particleData;
	public static AnimationData animationData;

	public static SelectionRectangle selectionRectangle;
	
	private static Timer gameTimer;
	public static boolean animationRunning;
    public static float stateTime;
    public static int gameSizeRatio;

    // TEST
    public static List<BaseRegion> positionPath;
	public static BaseRegion mover = null;
	
	public static List<BasePoint> swipePoints;
	public static boolean isSwiping;
	public static float swipeStartX, swipeEndX, swipeStartY, swipeEndY;

	public static boolean isMultiTouching;
	public static BasePoint initialMultiTouchPosition;
	public static BasePoint initialCameraPosition;
	public static List<BaseRegion> touchedList;
    // TEST
	
	public static void initialize(){
		
		gameSizeRatio = 10;
		
		if(!isInitialized){
			loadDefaultConstants();
			loadGameData();
			isInitialized = true;
		}
	}
	
	public static void run(){
		startTimer();
//		playerTouched((PlayerActor)gameData.getActor(1));
//		emptyScreenTouched(1500, 200);
//		ActionPack pack = new ActionPack();
//		Random r = new Random();
//		for (int i = 0; i < 2; i++) {
//			int x = r.nextInt(1400);
//			int y = r.nextInt(1000);
//			BaseRegion region = new BaseRegion(480, 360, defaultConstants.getActorRingHeight(), defaultConstants.getActorRingWidth());
//			pack.addAction(new OldMovementAction(gameData.getActor(2), region));
//			
//			ActionManager.addToQueue(new DexMissileAttackActionPack(gameData.getActor(3), gameData.getActor(2)));
//			
//			pack.addAction(new SteadyAction(100));
//			pack.addAction(new DexMissileAttackAction(gameData.getActor(3), gameData.getActor(2)));
//			pack.addAction(new SteadyAction(100));
//			
//			
//			pack.addAction(new OldMovementAction(gameData.getActor(4), gameData.getActor(0)));
//			pack.addAction(new SteadyAction(100));
//			x = r.nextInt(1400);
//			y = r.nextInt(1000);
//			region.setX(x);
//			region.setY(y);
//			pack.addAction(new DexTrailAttackAction(gameData.getActor(3), region));
//		}
//
//		ActionManager.addToQueue(pack);
//		ActionManager.addToQueueAsSeperateActions(pack2);
	}
	
	private static void loadDefaultConstants(){
		// TODO
		defaultConstants = new DefaultConstants(40, 30, 1.5f, 2);
		selectionRectangle = new SelectionRectangle();
	}
	
	private static void loadGameData(){
		actionData = new ActionData();
		gameData = new GameData();
		particleData = new ParticleData();
		animationData = new AnimationData();
		
		gameData.loadActorsFromJSON();
		ParticleManager.loadParticlesFromJSON();
		AnimationManager.loadAnimationsFromJSON();
		
		swipePoints = new ArrayList<BasePoint>();
		touchedList = new ArrayList<BaseRegion>();
		initialMultiTouchPosition = new BasePoint(0, 0);
		initialCameraPosition = new BasePoint(0, 0);
	}
	
	private static void startTimer(){
		gameTimer = new Timer();
		gameTimer.scheduleAtFixedRate(new GameTimer(), 0, 10);
	}

	public static void playerTouched(PlayerActor playerActor){
		gameData.selectSinglePlayer(playerActor);
	}
	
	public static void enemyTouched(EnemyActor enemyActor){
		if(gameData.isAnyPlayerSelected()){
			for(AbstractActor actor : gameData.getSelectedPlayerList()){
//				if(actor.isAttacking()){
//					ActionManager.addAttackingActor(actor, enemyActor);
//				}
//				else {
					ActionManager.addToQueue(new DexMissileAttackActionPack(actor, enemyActor));
//				}
			}
		}
	}
	
	public static void screenSwiped(){
		if(gameData.isAnyPlayerSelected()){
			for(AbstractActor actor : gameData.getSelectedPlayerList()){
				ActionManager.addToQueue(new DexTrailAttackActionPack(actor, new BaseRegion((swipeStartX + swipeEndX)/2, (swipeStartY + swipeEndY)/2, 5, 5)));
			}
		}
		isSwiping = false;
	}
	
	public static void emptyScreenTouched(int x, int y){
		if(gameData.isAnyPlayerSelected()){
			Game.mover = null;
			for(AbstractActor actor : gameData.getSelectedPlayerList()){
				BaseRegion targetRegion = BaseObject.fromCursorToMiddlePosition(x, y, actor);
				if(actor.isMoving()){
					actor.startMoving(targetRegion);
					gameData.addMovingObject(actor);
				}
				else {
					ActionManager.addToQueue(new MovementAction(actor, targetRegion, new WallHugDirectPathCalcSession()));
				}
				x += actor.width + 10;
			}
		}
	}
}
